package com.lry.pda.bottom.c.backend.executor;

import com.lry.pda.bottom.c.backend.code.CodeKey;
import com.lry.pda.bottom.c.backend.code.CodeNode;
import com.lry.pda.bottom.c.backend.type.Symbol;
import com.lry.pda.bottom.c.backend.type.TypeSystem;
import com.lry.pda.bottom.c.frontend.Grammar;

import java.util.ArrayList;
import java.util.List;

public class ExtDefExecutor extends BaseExecutor{

    private List<Object> argsList = new ArrayList<Object>();
    String funcName;
    @Override
    public void execute(CodeNode root) {
        int production = (int) root.getAttr(CodeKey.PRODUCTION);

        //FUNCT_DECL,COMPOUND_STMT -> EXT_DEF
        if(production== Grammar.OPT_SPECIFIERS_FUNCT_DECL_COMPOUND_STMT_TO_EXT_DEF){
            CodeNode child = root.getChildren().get(0);
            funcName = (String)child.getAttr(CodeKey.TEXT);
            root.setAttr(CodeKey.TEXT, funcName);

            saveArgs();
            executeChild(root, 0);


            executeChild(root, 1);
            if(null!=returnObj){
                root.setAttr(CodeKey.VALUE, returnObj);
                returnObj = null;
            }
            continueExecute = true;
            restoreArgs();

        }
    }


    private void saveArgs() {
        System.out.println("Save arguments....");
        List<Symbol> args = TypeSystem.getSelf().getSymbolsByScope(funcName);
        for (Symbol arg : args) {
            Object value = arg.getValue();
            argsList.add(value);
        }
    }

    private void restoreArgs() {
        System.out.println("Restore arguments....");
        List<Symbol> args = TypeSystem.getSelf().getSymbolsByScope(funcName);
        int count = 0;
        for (Symbol arg : args) {
            Object obj = argsList.get(count++);
            if(null!=obj){
                arg.setValue(obj);
            }
        }
    }

}
